﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GameEditor.Common;
using GameEditor.Common.Controls;
using GameEditor.Common.ComponentModel;
using System.Runtime.InteropServices;
using TaskSystemClient.SPM;

namespace TaskSystemClient
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public partial class TaskInformation : Form
    {
        static int lastTaskID=0;

        public TaskInformation()
        {
            InitializeComponent();

            comboBox_TaskPriority.Items.Clear();
            foreach (string s in TaskPriority.Priorities)
            {
                comboBox_TaskPriority.Items.Add(s);
            }

            comboBox_TaskState.Items.Clear();
            foreach (string s in TaskState.States)
            {
                comboBox_TaskState.Items.Add(s);
            }
        }

        private void TaskInformation_Load(object sender, EventArgs e)
        {
            if(currentTask!=null && currentTask.ID==lastTaskID)
            {

            }
            else
            {
                doSelectCurentTaskByID();
            }
        }

        private SPM.Task currentTask=null;
        private SPM.Task originalTask=null;

        public SPM.Task CurrentTask
        {
            get
            {
                return currentTask;
            }
        }

        public void LoadTask(SPM.Task _task)
        {
            originalTask = _task;
            currentTask = _task.Clone() as SPM.Task;

            lastTaskID = _task.ID;

            TaskToUI(currentTask);
        }
        public void TaskIDToUI(SPM.Task task)
        {
            this.label_TaskID.Text = task.ID.ToString();
        }
        public void TaskTitleToUI(SPM.Task task)
        {
            this.textBox_TaskTitle.Text = task.Title;
        }
        public void TaskMileStoneToUI(SPM.Task task)
        {
            this.textBox_MileStone.Text = task.MileStoneName;
        }
        public void TaskTagsToUI(SPM.Task task)
        {
            this.textBox_TaskTags.Text = task.Tags_ForDisplay;
        }
        public void TaskStateToUI(SPM.Task task)
        {
            this.comboBox_TaskState.Text = task.State;
            FontStyle fontStyle;
            Color foreColor;
            TaskTreeViewHelper.getStyleByTaskState(task, out fontStyle, out foreColor);
            comboBox_TaskState.Font = new Font(comboBox_TaskState.Font, fontStyle);
            comboBox_TaskState.ForeColor = foreColor;
        }
        public void TaskUserToUI(SPM.Task task)
        {
            this.textBox_TaskUser.Text = task.Users_ForDisplay;
        }
        public void TaskPriorityToUI(SPM.Task task)
        {
            this.comboBox_TaskPriority.Text = task.Priority;
            Color c=TaskPriorityEditorDelegate.GetPriorityColor(task);
            comboBox_TaskPriority.ForeColor = c;
        }
        public void TaskFinishTimeToUI(SPM.Task task)
        {
            this.label_FinishTime.Text = TaskFinishTimeEditorDelegate.FormatDateTime(task.FinishTime);
        }

        public void TaskDescriptionToUI(SPM.Task task)
        {
            Code = task.Description;
            webBrowser_TaskDescription.Navigate("about:blank");
            ExternalObjectHostHandler.SetExternalObject(webBrowser_TaskDescription.Document.DomDocument, this);
            webBrowser_TaskDescription.Navigate(PathManager.ExecutablePathRoot + @"\SPMData\fckeditor\editor.html?" + PathManager.ExecutablePathRoot);
        }
        void TaskToUI(SPM.Task task)
        {
            TaskIDToUI(task);
            TaskTitleToUI(task);
            TaskMileStoneToUI(task);
            TaskTagsToUI(task);
            TaskStateToUI(task);
            TaskUserToUI(task);
            TaskPriorityToUI(task);
            TaskFinishTimeToUI(task);
            TaskDescriptionToUI(task);
        }

        /**
         * 配合 webBrowser_TaskDescription 和 FCKEditor 使用
         * */
        public string Code
        {
            get
            {
                if (currentTask == null || currentTask.Description == null)
                    return string.Empty;
                return currentTask.Description;
            }
            set
            {
                if (currentTask != null)
                {
                    currentTask.Description = value;
                }
            }
        }
        public void DoExternalMessage(string msg)
        {
            ExternCommandHelper.ParseCommand(new string[] { msg }, true);
        }

        ///**
        // * ？？？
        // */
        //public bool hasChanged()
        //{
        //    if (currentTask != null)
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}

        public void Submit(string code, bool canSave)
        {
            Code = code;
        }
        protected override void OnClosing(CancelEventArgs e)
        {
            if(this.DialogResult == DialogResult.None)
            {
                getDescriptionFromWebControl();

                if (currentTask != null && !currentTask.IsTaskDataSame(originalTask))
                {
                    DialogResult ret = GameEditor.Common.Dialogs.ConfirmYesNoCancel(this,"当前任务已经被修改了，是否保存？", "保存数据");
                    if (ret == DialogResult.Yes)
                    {
                        tryDoSave();
                        this.DialogResult = DialogResult.Yes;
                    }
                    else if (ret == DialogResult.Cancel)
                    {
                        e.Cancel = true;
                    }
                }
                else
                {
                    this.DialogResult = DialogResult.No;
                }
            }
            base.OnClosing(e);
        }

        private bool getDescriptionFromWebControl()
        {
            if (currentTask != null)
            {
                try
                {
                    mshtml.IHTMLWindow2 window = webBrowser_TaskDescription.Document.Window.DomWindow as mshtml.IHTMLWindow2;
                    window.execScript("DoSubmitText(false)", "javascript");
                    return true;
                }
                catch (Exception ex)
                {
                    GameEditor.Common.Dialogs.ShowException(this,ex);
                    return false;
                }
            }
            return false;
        }

        private void button_FinishTime_Click(object sender, EventArgs e)
        {
            DatePicker picker = new DatePicker();
            picker.Date = currentTask.FinishTime == null ? DateTime.Today : currentTask.FinishTime;
            picker.DatePicked = delegate(DateTime? dateTime)
            {
                currentTask.FinishTime = dateTime;
                //提交成功，更新UI
                TaskFinishTimeToUI(currentTask);
            };
            picker.Show();
        }

        private void button_ChangeTask_Click(object sender, EventArgs e)
        {
            doSelectCurentTaskByID();
        }

        private void label_TaskID_DoubleClick(object sender, EventArgs e)
        {
            doSelectCurentTaskByID();
        }

        private void doSelectCurentTaskByID()
        {
            string taskIDString = lastTaskID.ToString();
            if (DialogResult.OK == GameEditor.Common.InputDialog.ShowDialog("选择新的任务", "请输入任务编号", ref taskIDString,
                delegate(string value)
                {
                    int i = 0;
                    bool r = int.TryParse(value, out i);
                    if (r == false)
                    {
                        throw new Exception("请输入一个整数");
                    }
                }
                ))
            {
                LoadTaskByIDString(taskIDString);
                return;

            }
        }

        private void LoadTaskByIDString(string taskIDString)
        {
            int newTaskID = 0;
            if (int.TryParse(taskIDString, out newTaskID))
            {
                if (currentTask != null && currentTask.ID == newTaskID)
                {
                    GameEditor.Common.Dialogs.Warning(this, string.Format("编号[{0}]的任务已经被载入了!", newTaskID), "警告");
                }
                else
                {


                    if (currentTask != null)
                    {
                        DialogResult ret = GameEditor.Common.Dialogs.ConfirmYesNoCancel(this,"当前任务可能已经被修改了，是否保存？", "保存数据");
                        if (ret == DialogResult.Cancel)
                        {
                            return;
                        }
                        if (ret == DialogResult.Yes)
                        {
                            tryDoSave();
                        }
                    }

                    LoadTaskByID(newTaskID);

                }
            }
        }



        public void LoadTaskByID(int newTaskID)
        {
            TaskData taskData = TaskManager.Instance.GetTaskDataFromCacheOrDB(newTaskID);
            if (taskData!=null)
            {
                this.LoadTask(taskData.Task);
            }
            else
            {
                GameEditor.Common.Dialogs.Warning(this,string.Format("编号[{0}]的任务不存在!", newTaskID), "警告");
            }
        }
        bool tryDoSave()
        {
            if (currentTask == null)
                return true;

            bool ret=getDescriptionFromWebControl();

            Task bak = originalTask.Clone() as Task;
            //首先把currentTask的数据复制到 originalTask 中，然后把 originalTask  保存任务数据到数据库
            originalTask.AssignFrom(currentTask);

            ObjectTransaction trans = new ObjectTransaction(originalTask, MainForm.GetCommitContext());
            if (!trans.Commit())
            {
                //没有提交成功，则回滚
                trans.Rollback();
                originalTask.AssignFrom(bak);
                GameEditor.Common.Dialogs.Warning(this,"把任务数据写回数据库时失败。", "保存数据");
                return false;
            }
            else
            {
                TaskData data = TaskManager.Instance[originalTask.ID];
                //提交成功，更新UI
                foreach (TreeListNode node in data.Nodes)
                {
                    TaskTreeViewHelper.UpdateTaskToTreeListNode(originalTask, node);
                }
            }
            return true;
        }
        private void button_SaveAndClose_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Yes;
            tryDoSave();
            this.Close();
        }

        private void button_Close_NoSave_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.No;
            this.Close();
        }

        private void button_TaskUser_Click(object sender, EventArgs e)
        {
            if (currentTask == null)
                return ;
            ChooseUser user = new ChooseUser();
            user.SelectedUsers = currentTask.Users;
            user.LoadUsers();
            user.UserSelected += new EventHandler(
                delegate(object sender_, EventArgs e_)
                {
                    StringBuilder sb = new StringBuilder();
                    string[] selectedUsers = user.SelectedUsers;
                    currentTask.Users = selectedUsers;
                    TaskUserToUI(currentTask);
                });
            user.Show();
        }

        private void button_TaskTags_Click(object sender, EventArgs e)
        {
            if(currentTask==null)
            {
                return;
            }
            ChooseTags dialog = new ChooseTags();
            dialog.Tags = currentTask.GetTags();
            dialog.OnTagChoosed += new EventHandler(
                delegate(object sender_, EventArgs e_)
                {
                    currentTask.SetTags(dialog.Tags);
                    TaskTagsToUI(currentTask);
                });
            dialog.Show();
        }

        private void button_TaskMileStone_Click(object sender, EventArgs e)
        {
            if(currentTask==null)
            {
                return;
            }
            using (ChooseMileStone dialog = new ChooseMileStone())
            {
                dialog.SelectedMileStoneCode = currentTask.MileStoneCode;

                if (dialog.ShowDialog() != DialogResult.OK)
                    return;

                string selectedMileStoneCode = dialog.SelectedMileStoneCode;
                currentTask.MileStoneCode = selectedMileStoneCode;

                TaskMileStoneToUI(currentTask);
            }
        }

        private void button_ReloadTaskToUI_Click(object sender, EventArgs e)
        {
            if (originalTask != null)
            {
                currentTask = originalTask.Clone() as SPM.Task;
                TaskToUI(currentTask);
            }
        }

        private void textBox_TaskTitle_TextChanged(object sender, EventArgs e)
        {
            if(currentTask==null)
            {
                return;
            }
            currentTask.Title = textBox_TaskTitle.Text;
        }

        private void comboBox_TaskState_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (currentTask==null)
            {
                return;
            }
            currentTask.State = comboBox_TaskState.Items[comboBox_TaskState.SelectedIndex] as string;
            TaskStateToUI(currentTask);
        }

        private void comboBox_TaskPriority_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (currentTask == null)
            {
                return;
            }
            currentTask.Priority = comboBox_TaskPriority.Items[comboBox_TaskPriority.SelectedIndex]as string;
            TaskPriorityToUI(currentTask);
        }
    }
}
